package jmind.core.aspect;

import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 *  Spring事务处理时自我调用的解决方案
 *  https://my.oschina.net/longyuan/blog/714355
 *  http://kld208.iteye.com/blog/1632935
 *  http://blog.csdn.net/wxwzy738/article/details/27566645
 *   AopContext.currentProxy()
 * @author xieweibo
 * @date 2016年3月17日
 */
public class InjectBeanSelfProcessor implements BeanPostProcessor, ApplicationContextAware {
    private ApplicationContext context;

    //① 注入ApplicationContext
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (!(bean instanceof BeanSelfAware)) { //② 如果Bean没有实现BeanSelfAware标识接口 跳过
            return bean;
        }
        if (AopUtils.isAopProxy(bean)) { //③ 如果当前对象是AOP代理对象，直接注入
            ((BeanSelfAware) bean).setSelf(bean);
        } else {
            //④ 如果当前对象不是AOP代理，则通过context.getBean(beanName)获取代理对象并注入
            //此种方式不适合解决prototype Bean的代理对象注入
            ((BeanSelfAware) bean).setSelf(context.getBean(beanName));
        }
        return bean;
    }

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }
}